<template>
  <n-card :bordered="false" class="domain-container card-container">
    <template #header>
      <n-input v-model:value="domainTable.search"
               @update:value="searchData"
               v-if="domainTable.checkedRowKeys.length === 0"
               :disabled="domainStore.loading"
               class="w-80" placeholder="支持域名、备注查询" size="large">
        <template #prefix>
          <img :src="`${mainStore.commonImagePath}/icon_search.svg`" alt="icon_search">
        </template>
      </n-input>
      <n-space v-else :item-style="{height: '32px'}" align="center">
        <n-tag :bordered="false" class="text-base bg-transparent" type="primary">
          已选择 {{ domainTable.checkedRowKeys.length }} 条
        </n-tag>
        <n-tag class="text-base cursor-pointer bg-transparent hover:bg-[#F7F9FFFF]" :bordered="false"
               @click="deleteDomain">
          <template #avatar>
            <img :src="`${mainStore.commonImagePath}/icon_delete_download.svg`" alt="icon_delete_download" width="24"/>
          </template>
          删除
        </n-tag>
      </n-space>
    </template>
    <template #header-extra>
      <n-button class="px-4" size="large" type="primary" :disabled="domainStore.loading"
                @click="domainState.showModal = true">
        <template #icon>
          <img :src="`${mainStore.commonImagePath}/link_union_btn.svg`" alt="link_union_btn">
        </template>
        添加{{ title }}
      </n-button>
    </template>
    <n-data-table :bordered="false" :scroll-x="$route.meta.type === 2 ? undefined : 1580" :loading="domainStore.loading"
                  :checked-row-keys="domainTable.checkedRowKeys" @update:checked-row-keys="handleCheck" size="large"
                  :columns="unref($route.meta.type === 2 ? domainTable.manageColumns : domainTable.domainColumns)"
                  :data="domainStore.domainList" :row-key="row => row.id" flex-height>
      <template #empty>
        <n-space align="center" justify="center" vertical>
          <img :src="`${mainStore.commonImagePath}/empty_bg.svg`" alt="empty_bg">
          <n-text class="text-[#96A0B1]">暂无数据</n-text>
        </n-space>
      </template>
    </n-data-table>
  </n-card>

  <n-modal v-model:show="domainState.showModal" :auto-focus="false" :bordered="false" :closeOnEsc="false"
           :loading="domainState.loading" :mask-closable="false" :closable="!domainState.loading"
           :negative-button-props="{size:'large', disabled:domainState.loading}"
           :positive-button-props="{size:'large', type:'primary'}" :show-icon="false" :title="`添加${title}`"
           class="w-[480px]" negative-text="取消" positive-text="确认" preset="dialog" size="large" to="#app"
           @close="closeModal" @negative-click="closeModal" @positive-click="submitAddDomain">
    <n-form ref="addDomainFormRef" :model="domainState.form" :rules="domainState.rules" label-placement="left">
      <n-form-item label="域名用途：" path="types">
        <n-radio-group v-model:value="domainState.form.types" name="types" :disabled="domainState.loading">
          <n-space v-if="$route.meta.type === 2">
            <n-radio :value="0">域名黑名单</n-radio>
            <n-radio :value="1">IP黑名单</n-radio>
          </n-space>
          <n-space v-else>
            <n-radio :value="0">通用域名</n-radio>
            <n-radio :value="1">微信域名</n-radio>
            <n-radio :value="2">QQ专用</n-radio>
          </n-space>
        </n-radio-group>
      </n-form-item>
      <n-form-item path="value">
        <n-input v-model:value="domainState.form.value" :autosize="{minRows: 7, maxRows: 7}"
                 :disabled="domainState.loading"
                 :placeholder="$route.meta.type === 2 ? '每行一条' : `每行一条
泛域名格式：*.domain.cn
例如：*.aeink.com
通用域名两者皆检测`" type="textarea"/>
      </n-form-item>
    </n-form>
  </n-modal>
</template>

<script setup>
import {reactive, ref, unref, h, getCurrentInstance} from 'vue'
import {useRouter, useRoute, onBeforeRouteUpdate} from 'vue-router'
import {NButton, NEllipsis, NInput, NSpace, NTag, NText, NBadge} from 'naive-ui'
import {useDebounceFn} from '@vueuse/core'
import {useDialog} from '@/hook/popup/dialog'
import {useMainStore, useDomainStore} from '@/store'
import {addDomain, delDomain, batchDelDomain, modifyDomain} from '@api/domainApi'
import {useApi} from '@/axios/tool/useRequest'

const {proxy} = getCurrentInstance()
const router = useRouter()
const route = useRoute()
const domainStore = useDomainStore()
const mainStore = useMainStore()
const title = ref(route.meta.type === 2 ? '黑名单' : route.meta.title)

const handleTableStatusField = status => (h(NSpace, {
  size: [8, 5],
  justify: 'center',
  class: 'rounded w-16 h-8 text-base border border-[#E7EBEF] bg-white'
}, {
  default: () => [
    h(NBadge, {
      type: status ? 'info' : 'error',
      dot: true
    }),
    h(NText, {
      type: status ? 'primary' : 'error',
    }, {default: () => status ? '正常' : '异常'})
  ]
}))

const domainTable = reactive({
  search: '',
  domainColumns: [
    {type: 'selection', fixed: 'left'},
    {
      title: '域名', key: 'domain', fixed: 'left', width: 220,
      render(row) {
        return h('div', {}, {
          default: () => [
            h(NEllipsis, {
              class: 'text-[rgba(0,0,0,0.9)]'
            }, {default: () => row.domain}),
            h(NEllipsis, {
              class: 'text-[rgba(0,0,0,0.6)] text-xs'
            }, {default: () => `添加时间：${row.create_time}`})
          ]
        })
      }
    },
    {
      title: '备注', key: 'remarks', width: 150,
      render(row) {
        return h(NInput, {
          placeholder: '请输入备注',
          bordered: false,
          defaultValue: row.remarks,
          class: 'text-[#00000099]',
          async onChange(value) {
            const res = await modifyDomain(row.id, {remarks: value, type: route.meta.type})
            if (res?.code === 0) {
              domainStore.updateDomainList(res.data)
              $message.success(res.msg)
            }
          }
        })
      }
    },
    {
      title: '次数', key: 'count', width: 80,
      render(row) {
        return h(NText, {
          strong: true,
          class: 'text-[rgba(0,0,0,0.9)]'
        }, {default: () => row.count})
      }
    },
    {
      title: '类型', key: 'types', width: 160,
      render(row) {
        return h(NTag, {
          type: row.types === 0 ? 'primary' : row.types === 1 ? 'success' : 'warning',
          size: 'large',
          bordered: false,
          class: 'rounded px-6',
        }, {default: () => row.types === 0 ? '通用域名' : row.types === 1 ? '微信域名' : 'QQ专用'})
      }
    },
    {
      title: 'QQ状态',
      render(row) {
        return handleTableStatusField(row.status.qq)
      }
    },
    {
      title: '微信状态',
      render(row) {
        return handleTableStatusField(row.status.wechat)
      }
    },
    {
      title: '抖音状态',
      render(row) {
        return handleTableStatusField(row.status.tiktok)
      }
    },
    {
      title: '快手状态',
      render(row) {
        return handleTableStatusField(row.status.kuaishou)
      }
    },
    {
      title: '微博状态',
      render(row) {
        return handleTableStatusField(row.status.weibo)
      }
    },
    {
      title: '支付宝状态',
      render(row) {
        return handleTableStatusField(row.status.alipay)
      }
    },
    {
      title: '知乎状态',
      render(row) {
        return handleTableStatusField(row.status.zhihu)
      }
    },
    {
      title: '操作', fixed: 'right', width: 110,
      render(row) {
        return h(NSpace, {}, {
          default: () => h(NButton, {
            text: true,
            disabled: domainTable.disabledBtn,
            title: '删除',
            onclick() {
              deleteDomain(row.id)
            }
          }, {
            default: () => h('img', {
              src: `${mainStore.commonImagePath}/link_delete_normal.svg`,
              alt: 'link_delete_normal',
            })
          })
        })
      }
    },
  ],
  manageColumns: [
    {type: 'selection', fixed: 'left'},
    {
      title: '黑名单', key: 'domain', fixed: 'left',
      render(row) {
        return h(NEllipsis, {
          class: 'text-[rgba(0,0,0,0.9)]'
        }, {default: () => row.domain})
      }
    },
    {
      title: '备注', key: 'remarks', width: 170,
      render(row) {
        return h(NInput, {
          placeholder: '请输入备注',
          bordered: false,
          defaultValue: row.remarks,
          async onChange(value) {
            const res = await modifyDomain(row.id, {remarks: value, type: route.meta.type})
            if (res?.code === 0) {
              domainStore.updateDomainList(res.data)
              $message.success(res.msg)
            }
          }
        })
      }
    },
    {
      title: '添加时间', key: 'create_time',
      render(row) {
        return h(NText, {
          strong: true,
          class: 'text-[rgba(0,0,0,0.6)]'
        }, {default: () => row.create_time})
      }
    },
    {
      title: '类型', key: 'types',
      render(row) {
        return h(NTag, {
          size: 'large',
          bordered: false,
          class: 'w-28 rounded flex justify-center',
          color: {color: row.types === 0 ? '#E9EBFD' : '#EDEFF6'}
        }, {default: () => row.types === 0 ? '域名黑名单' : 'IP黑名单'})
      }
    },
    {
      title: '操作', fixed: 'right', width: 140,
      render(row) {
        return h(NSpace, {}, {
          default: () => h(NButton, {
            text: true,
            disabled: domainTable.disabledBtn,
            title: '删除',
            onclick() {
              deleteDomain(row.id)
            }
          }, {
            default: () => h('img', {
              src: `${mainStore.commonImagePath}/link_delete_normal.svg`,
              alt: 'link_delete_normal',
            })
          })
        })
      }
    },
  ],
  checkedRowKeys: [],
  disabledBtn: false,
})

domainStore.getDomainList(route.meta.type, domainTable.search)
onBeforeRouteUpdate(to => {
  title.value = to.meta.type === 2 ? '黑名单' : to.meta.title
  domainStore.getDomainList(to.meta.type, domainTable.search)
  domainState.form.type = to.meta.type
  domainTable.checkedRowKeys = []
  domainTable.disabledBtn = false
})

const searchData = useDebounceFn(() => domainStore.getDomainList(route.meta.type, domainTable.search), 350)

const handleCheck = rowKeys => {
  domainTable.disabledBtn = rowKeys.length > 0
  domainTable.checkedRowKeys = rowKeys
}

const deleteDomain = id => {
  const isBatch = domainTable.checkedRowKeys.length > 0
  const type = route.meta.type, ids = domainTable.checkedRowKeys
  const {loading, result, request} = useApi(isBatch ? batchDelDomain({ids, type}) : delDomain(id, {type}))
  useDialog({
    title: '删除',
    content: `确定删除${isBatch ? '这些' : '该'}${title.value}吗？`,
    loading: loading,
    async confirm() {
      await request()
      if (result.value?.code === 0) {
        $message.success(result.value.msg)
        domainStore.updateDomainList(result.value.data)
        if (isBatch) {
          domainTable.checkedRowKeys = []
          domainTable.disabledBtn = false
        }
      }
    }
  })
}

const defaultDomainFormModel = () => ({
  value: '',
  type: route.meta.type,
  types: 0,
})

const domainState = reactive({
  showModal: false,
  loading: false,
  form: defaultDomainFormModel(),
  rules: {
    value: [
      {required: true, message: '输入不能为空', trigger: 'input'}
    ]
  }
})

const removeEmpty = arr => {// 清除数组中的空值
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] === '' || typeof (arr[i]) == 'undefined' || arr[i] == null) {
      arr.splice(i, 1)
      i -= 1 // 删除空元素后，循环的下标减1
    }
  }
  return arr
}

const closeModal = () => {
  proxy.$refs.addDomainFormRef?.restoreValidation()
  domainState.form = Object.assign(unref(domainState.form), defaultDomainFormModel())
}

const submitAddDomain = () => {
  return new Promise(((resolve, reject) => {
    proxy.$refs.addDomainFormRef?.validate(async validate => {
      if (validate) return reject(false)
      domainState.form.domain = removeEmpty(domainState.form.value.trim().split('\n'))
      const {loading, result, request} = useApi(addDomain(domainState.form))
      domainState.loading = loading
      await request()
      if (result.value?.code !== 0) return false
      $message.success(result.value.msg)
      domainStore.updateDomainList(result.value.data)
      closeModal()
      resolve(true)
    })
  }))
}
</script>

<style lang="less" scoped>
.domain-container {
  &:deep(.n-card__content) {
    .n-badge {
      padding-bottom: 2px;

      .n-badge-sup {
        width: 6px;
        height: 6px;
        min-width: 6px;
      }
    }
  }
}
</style>
